home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / circuits / irsim-9.000 / irsim-9 / calibrate / findr.c < prev    next >
C/C++ Source or Header  |  1991-04-08  |  9KB  |  427 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4.  
  5. typedef struct
  6.   {
  7.     char    *name;
  8.     double  *vals;
  9.     double  hl_t;
  10.     double  lh_t;
  11.     double  tphl;
  12.     double  tplh;
  13.   } Signal;
  14.  
  15.  
  16. struct
  17.   {
  18.     int     nv;
  19.     int     np;
  20.     Signal  *sigs;
  21.   } plot;
  22.  
  23. typedef struct
  24.   {
  25.     double  w, l;
  26.   } TranSz;
  27.  
  28.  
  29. double midpoint;
  30.  
  31. Signal *timev, *in1, *in2, *in3, *out1, *out2, *out3, *out4;
  32.  
  33.  
  34. main( argc, argv )
  35.   int   argc;
  36.   char  *argv[];
  37.   {
  38.     FILE    *fi = stdin;
  39.     TranSz  p, n;
  40.     double  cap;
  41.     int     i;
  42.  
  43.     cap = p.w = p.l = n.w = n.l = -1;
  44.     for( i = 1; i < argc; i++ )
  45.       {
  46.     if( argv[i][0] == '-' )
  47.       {
  48.         switch( argv[i][1] )
  49.           {
  50.         case 'c' :
  51.             i++;
  52.             if( i >= argc ) usage( "missing argument :" );
  53.             if( sscanf( argv[i], "%lf", &cap ) != 1 || cap <= 0 )
  54.             usage( "bad argument for 'c': " );
  55.             cap *= 1E-15;    /* convert to ff */
  56.             break;
  57.         case 'n' :
  58.             i++;
  59.             if( i >= argc ) usage( "missing argument :" );
  60.             if( sscanf( argv[i], "%lf,%lf", &n.w, &n.l ) != 2 ||
  61.               n.w <= 0 || n.l <= 0 )
  62.             usage( "bad argument for 'n': " );
  63.             break;
  64.         case 'p' :
  65.             i++;
  66.             if( i >= argc ) usage( "missing argument :" );
  67.             if( sscanf( argv[i], "%lf,%lf", &p.w, &p.l ) != 2 ||
  68.               p.w <= 0 || p.l <= 0 )
  69.             usage( "bad argument for 'p': " );
  70.             break;
  71.         default :
  72.             usage( "unknown switch :" );
  73.           }
  74.       }
  75.     else
  76.       {
  77.         if( (fi = fopen( argv[i], "r" )) == NULL )
  78.         usage( "can not open input file :" );
  79.       }
  80.       }
  81.  
  82.     if( cap <= 0 || n.l <= 0 || n.w <= 0 || p.l <= 0 || p.w <= 0 )
  83.     usage( "i am missing parameters:" );
  84.  
  85.     if( read_header( fi ) == 0 )
  86.     exit( 1 );
  87.     if( read_variables( fi ) == 0 )
  88.     exit( 1 );
  89.     if( read_values( fi ) == 0 )
  90.     exit( 1 );
  91.     if( find_delays() == 0 )
  92.     exit( 1 );
  93.  
  94.     PrintResistEntries( cap, &n, &p );
  95.     exit( 0 );
  96.   }
  97.  
  98.  
  99. usage( s )
  100.   char *s;
  101.   {
  102.     fprintf( stderr, "%s\n", s );
  103.     fprintf( stderr, "usage: findr -c <cap> -nfet <w,l> -pfet <w,l> [rawfile]\n" );
  104.     fprintf( stderr, "\tcap     -> loading capacitance (in fF)\n" );
  105.     fprintf( stderr, "\tw,l     -> width, length of fet (in um)\n" );
  106.     fprintf( stderr, "\trawfile -> spice rawfile (ascii)\n" );
  107.     exit( 1 );
  108.   }
  109.  
  110.  
  111. #define eqsubstr( VS, FS )    ( strncmp( (VS), FS, sizeof( FS ) -1 ) == 0 )
  112.  
  113. int read_header( f )
  114.   FILE  *f;
  115.   {
  116.     char  line[512];
  117.     int   plotname = 0;
  118.     char  *s;
  119.  
  120.     while( fgets( line, 512, f ) )
  121.       {
  122.     if( eqsubstr( line, "Title:" ) )
  123.         ;
  124.     else if( eqsubstr( line, "Date:" ) )
  125.         ;
  126.     else if( eqsubstr( line, "Plotname:" ) )
  127.         plotname = 1;
  128.     else if( eqsubstr( line, "Flags:" ) )
  129.         ;
  130.     else if( eqsubstr( line, "Command:" ) )
  131.         ;
  132.     else if( eqsubstr( line, "No. Variables:" ) )
  133.       {
  134.         if( plotname == 0 )
  135.           {
  136.         fprintf( stderr, "missing Plotname entry\n" );
  137.         return( 0 );
  138.           }
  139.         for( s = line; *s != ':'; s++ );
  140.         s++;
  141.         if( sscanf( s, "%d", &plot.nv ) != 1 || plot.nv <= 0 )
  142.           {
  143.         fprintf( stderr, "bad line: %s", line );
  144.         return( 0 );
  145.           }
  146.       }
  147.     else if( eqsubstr( line, "No. Points:" ) )
  148.       {
  149.         if( plotname == 0 )
  150.           {
  151.         fprintf( stderr, "missing Plotname entry\n" );
  152.         return( 0 );
  153.           }
  154.         for( s = line; *s != ':'; s++ );
  155.         s++;
  156.         if( sscanf( s, "%d", &plot.np ) != 1 || plot.np <= 0 )
  157.           {
  158.         fprintf( stderr, "bad line: %s", line );
  159.         return( 0 );
  160.           }
  161.       }
  162.     else if( eqsubstr( line, "Variables:" ) )
  163.       {
  164.         if( plotname == 0 || plot.np == 0 | plot.nv == 0 )
  165.           {
  166.         fprintf( stderr, "missing entries:%s%s%s\n",
  167.           (plotname) ? "" : " 'Plotname'",
  168.           (plot.nv) ? "" : " 'No. Variables'",
  169.           (plot.np) ? "" : " 'No. Points'" );
  170.           }
  171.         return( 1 );
  172.       }
  173.     else
  174.       {
  175.         fprintf( stderr, "Unrecognized line: %s", line );
  176.         return( 0 );
  177.       }
  178.       }
  179.     fprintf( stderr, "premature EOF\n" );
  180.     return( 0 );
  181.   }
  182.  
  183.  
  184.  
  185. int read_variables( f )
  186.   FILE  *f;
  187.   {
  188.     char    line[200], name[100], type[100];
  189.     int     i;
  190.     int     ix;
  191.     double  *v;
  192.     char    *s, *p;
  193.  
  194.     plot.sigs = (Signal *) calloc( plot.nv, sizeof( Signal ) );
  195.     if( plot.sigs == NULL )
  196.       {
  197.     fprintf( stderr, "no memory\n" );
  198.     return( 0 );
  199.       }
  200.  
  201.     for( i = 0; i < plot.nv; i++ )
  202.       {
  203.     if( fgets( line, 200, f ) == NULL )
  204.       {
  205.         fprintf( stderr, "premature EOF\n" );
  206.         return( 0 );
  207.       }
  208.     if( sscanf( line, "%d %s %s", &ix, name, type ) != 3 )
  209.       {
  210.         fprintf( stderr, "bad 'variable' line: %s", line );
  211.         return( 0 );
  212.       }
  213.     s = (char *) malloc( strlen( name ) + 1 );
  214.     v = (double *) calloc( plot.np, sizeof( double ) );
  215.     if( v == NULL || s == NULL )
  216.       {
  217.         fprintf( stderr, "no memory\n" );
  218.         return( 0 );
  219.       }
  220.     plot.sigs[i].vals = v;
  221.     plot.sigs[i].name = s;
  222.     for( p = name; *p != '\0'; p++, s++ )
  223.         *s = ( isupper( *p ) ) ? tolower( *p ) : *p;
  224.     *s = '\0';
  225.       }
  226.  
  227.     if( fgets( line, 100, f ) == NULL )
  228.       {
  229.     fprintf( stderr, "premature EOF\n" );
  230.     return( 0 );
  231.       }
  232.     if( eqsubstr( line, "Values:" ) )
  233.     return( 1 );
  234.  
  235.     fprintf( stderr, "No 'Values' line\n" );
  236.     return( 0 );
  237.   }
  238.  
  239.  
  240. int read_values( f )
  241.   FILE  *f;
  242.   {
  243.     char    line[200];
  244.     int     n, i, n_p, z;
  245.     double  v;
  246.  
  247.     for( n = 0; n < plot.np; n++ )
  248.       {
  249.     if( fgets( line, 200, f ) == NULL )
  250.       {
  251.         fprintf( stderr, "premature EOF\n" );
  252.         return( 0 );
  253.       }
  254.  
  255.     if( sscanf( line, "%d%lf", &n_p, &v ) != 2 || n_p != n )
  256.       {
  257.         fprintf( stderr, "bad 'value' line: %s", line );
  258.         return( 0 );
  259.       }
  260.  
  261.     plot.sigs[0].vals[n] = v;
  262.     for( i = 1; i < plot.nv; i++ )
  263.       {
  264.         if( fgets( line, 200, f ) == NULL )
  265.           {
  266.         fprintf( stderr, "premature EOF\n" );
  267.         return( 0 );
  268.           }
  269.         if( sscanf( line, "%lf", &v ) != 1 )
  270.           {
  271.         fprintf( stderr, "bad 'value' line: %s", v, line );
  272.         return( 0 );
  273.           }
  274.         plot.sigs[i].vals[n] = v;
  275.       }
  276.       }
  277.     return( 1 );
  278.   }
  279.  
  280.  
  281. Signal *find( name )
  282.   char  *name;
  283.   {
  284.     int     i;
  285.     Signal  *sig;
  286.  
  287.     for( i = 0, sig = plot.sigs; i < plot.nv; i++, sig++ )
  288.       {
  289.     if( strcmp( name, sig->name ) == 0 )
  290.         return( sig );
  291.       }
  292.     return( NULL );
  293.   }
  294.  
  295.  
  296. double interp( y, v1, v2, t1, t2 )
  297.   double y, v1, v2, t1, t2;
  298.   {
  299.     return( t2 + (y - v2) * (t2 - t1) / (v2 - v1) );
  300.   }
  301.  
  302.  
  303. #define    L_H    1
  304. #define    H_L    2
  305. #define BOTH    ( L_H | H_L )
  306.  
  307. Signal *FindTransitions( name, which )
  308.   char  *name;
  309.   int   which;
  310.   {
  311.     Signal  *sig;
  312.     double  *v, *t;
  313.     int     i;
  314.  
  315.     if( (sig = find( name )) == NULL )
  316.       {
  317.     fprintf( stderr, "signal '%s' missing\n" );
  318.     return( NULL );
  319.       }
  320.     v = sig->vals;
  321.     t = timev->vals;
  322.  
  323.     if( which & L_H )
  324.       {
  325.     for( i = 1; i < plot.np; i++ )
  326.       {
  327.         if( v[i-1] < midpoint && v[i] >= midpoint )
  328.         goto foundlh;
  329.       }
  330.     fprintf( stderr, "signal '%s' has no l->h transition\n", name );
  331.     return( NULL );
  332.  
  333.       foundlh :
  334.     sig->lh_t = interp( midpoint, v[i-1], v[i], t[i-1], t[i] );
  335.       }
  336.  
  337.     if( which & H_L )
  338.       {
  339.     for( i = 1; i < plot.np; i++ )
  340.       {
  341.         if( v[i-1] > midpoint && v[i] <= midpoint )
  342.         goto foundhl;
  343.       }
  344.     fprintf( stderr, "signal '%s' has no h->l transition\n", name );
  345.     return( NULL );
  346.  
  347.       foundhl :
  348.     sig->hl_t = interp( midpoint, v[i-1], v[i], t[i-1], t[i] );
  349.       }
  350.  
  351.     return( sig );
  352.   }
  353.  
  354.  
  355. int find_delays()
  356.   {
  357.     Signal  *vdd;
  358.  
  359.     if( (timev = find( "time" )) == NULL )
  360.       {
  361.     fprintf( stderr, "variable 'time' missing\n" );
  362.     return( 0 );
  363.       }
  364.     if( (vdd = find( "vdd" )) == NULL )
  365.       {
  366.     fprintf( stderr, "variable 'vdd' missing\n" );
  367.     return( 0 );
  368.       }
  369.     midpoint = vdd->vals[0] / 2.0;
  370.  
  371.     if( (in1 = FindTransitions( "in1", BOTH )) == NULL ) return( 0 );
  372.     if( (in2 = FindTransitions( "in2", L_H )) == NULL ) return( 0 );
  373.     if( (in3 = FindTransitions( "in3", H_L )) == NULL ) return( 0 );
  374.     if( (out1 = FindTransitions( "out1", BOTH )) == NULL ) return( 0 );
  375.     if( (out2 = FindTransitions( "out2", BOTH )) == NULL ) return( 0 );
  376.     if( (out3 = FindTransitions( "out3", L_H )) == NULL ) return( 0 );
  377.     if( (out4 = FindTransitions( "out4", H_L )) == NULL ) return( 0 );
  378.  
  379.     out1->tphl = out1->hl_t - in1->lh_t;
  380.     out1->tplh = out1->lh_t - in1->hl_t;
  381.  
  382.     out2->tphl = out2->hl_t - out1->lh_t;
  383.     out2->tplh = out2->lh_t - out1->hl_t;
  384.  
  385.     out3->tplh = out3->lh_t - in2->lh_t;
  386.     out4->tphl = out4->hl_t - in3->hl_t;
  387.  
  388.     return( 1 );
  389.   }
  390.  
  391.  
  392. #define    SQ( A )        ( (A) * (A) )
  393.  
  394. PrintResistEntries( cap, ns, ps )
  395.   double  cap;
  396.   TranSz  *ns, *ps;
  397.   {
  398.     double  dyn_h, dyn_l, stat;
  399.  
  400.     dyn_h = out3->tplh / cap;
  401.     dyn_l = out1->tphl / cap;
  402.     stat = ( SQ( out2->tphl ) - SQ( out1->tphl ) ) / (out1->tplh * cap );
  403.     PrintR( "n-channel", ns->w, ns->l, dyn_h, dyn_l, stat ); 
  404.  
  405.     printf( "\n" );
  406.  
  407.     dyn_h = out1->tplh / cap;
  408.     dyn_l = out4->tphl / cap;
  409.     stat = ( SQ( out2->tplh ) - SQ( out1->tplh ) ) / (out1->tphl * cap );
  410.     PrintR( "p-channel", ps->w, ps->l, dyn_h, dyn_l, stat ); 
  411.   }
  412.  
  413.  
  414. #define    round( A )    (int) ( (A) + 0.5 )
  415.  
  416.  
  417. PrintR( ttype, w, l, rh, rl, rs )
  418.   char    *ttype;
  419.   double  w, l, rh, rl, rs;
  420.   {
  421.     static char *fmt = "resistance %s %s\t%.1f\t%.1f\t%d.0\n";
  422.  
  423.     printf( fmt, ttype, "dynamic-high", w, l, round( rh ) );
  424.     printf( fmt, ttype, "dynamic-low\t", w, l, round( rl ) );
  425.     printf( fmt, ttype, "static\t", w, l, round( rs ) );
  426.   }
  427.